package com.snap.awesomeserial.ui.widget;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.text.Editable;
import android.text.InputFilter;
import android.text.InputType;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;


import com.snap.awesomeserial.R;
import com.snap.awesomeserial.utils.ToastUtils;

import java.util.Timer;
import java.util.TimerTask;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import me.jessyan.autosize.utils.AutoSizeUtils;

public class DialogView2 {
    private int MAX_LENGTH = 20;
    private final ImageView warnTipIv;
    private final View cancelLl;
    private LinearLayout editLl;
    private TextView contentTv;
    private Context context;
    private ImageView clearTv;
    private TextView titleTv;
    private EditText edit;
    private TextView sureTv;
    private TextView cancelTv;
    private View layout;
    private AlertDialog dialog;
    private OnSureListener listener;
    private OnCancelListener cancelListener;
    private boolean hideInput = false;
    private boolean allowNull;
    private boolean dismissDialog = true;
    private boolean isCanceledOnTouchOutside = true;


    public DialogView2(Context context) {
        this.context = context;
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        LayoutInflater inflater = LayoutInflater.from(context);
        layout = inflater.inflate(R.layout.dialog_view2, null);
        sureTv = layout.findViewById(R.id.sure);
        cancelLl = layout.findViewById(R.id.cancel_ll);
        warnTipIv = layout.findViewById(R.id.warn_tip_iv);
        cancelTv = layout.findViewById(R.id.cancel);
        edit = layout.findViewById(R.id.edit);
        titleTv = layout.findViewById(R.id.title_tv);
        clearTv = layout.findViewById(R.id.clear_tv);
        contentTv = layout.findViewById(R.id.content_tv);
        editLl = layout.findViewById(R.id.edit_ll);
        dialog = builder.create();
    }

    /**
     * 特殊字符过滤：只能输入数字、字母、小数点、下划线、横杠、中文
     *
     * @return 表达式
     */
    public static String getSpecialCharFilter() {
        String regex = "^[0-9|a-zA-Z|.|_|\\-|\u4e00-\u9fa5]+$";

        return regex;
    }

    public DialogView2 setTitle(String title) {
        if (titleTv != null) {
            titleTv.setText(title);
        }
        return this;
    }

    /**
     * 在对话框弹出来的时候，EditText获取焦点，并弹出软键盘
     *
     * @param editText 编辑框
     */
    private void showSoftInputFromWindow(EditText editText) {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                ((Activity) context).runOnUiThread(() -> {
                    editText.setFocusable(true);
                    editText.setFocusableInTouchMode(true);
                    editText.requestFocus();
                    InputMethodManager inputManager =
                            (InputMethodManager) editText.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                    if (inputManager != null) {
                        inputManager.showSoftInput(editText, 0);
                    }
                });
            }
        }, 200);
    }

    public void show() {
        dialog.show();
        dialog.setCanceledOnTouchOutside(isCanceledOnTouchOutside);
        Window window = dialog.getWindow();
        if (window != null) {
            //自定义布局应该在这里添加，要在dialog.show()的后面
            window.setContentView(layout);
            //允许弹出系统键盘
            window.clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
            window.setLayout(AutoSizeUtils.dp2px(context, 296), WindowManager.LayoutParams.WRAP_CONTENT);
            //设置背景颜色
            window.setBackgroundDrawable(ContextCompat.getDrawable(context, R.drawable.bg_white_r8));
        }
        if (!hideInput) {
            showSoftInputFromWindow(edit);
        }
        sureTv.setOnClickListener(v -> {
            String content = null;
            if (edit.getText() != null) content = edit.getText().toString();
            if (content.isEmpty() && editLl.getVisibility() != View.GONE && !allowNull) {
                ToastUtils.get().showText("输入不能为空");
                return;
            }
            if (content.trim().equals(".")) {
                ToastUtils.get().showText("不允许只输入小数点");
                return;
            }
            if (dismissDialog) {
                dialog.dismiss();
            }
            if (listener != null)
                listener.onSureClick(content);
        });
        cancelTv.setOnClickListener(v -> {
            dialog.dismiss();
            if (cancelListener != null) {
                cancelListener.onCancelClick();
            }
        });
        clearTv.setOnClickListener(v -> edit.setText(""));
        edit.setSelection(edit.getText().length());
        InputFilter typeFilter = (source, start, end, dest, dstart, dend) -> {
            Pattern p = Pattern.compile(getSpecialCharFilter());
            Matcher m = p.matcher(source.toString());
            if (!m.matches()) {
                return "";
            }
            return null;
        };
        edit.setFilters(new InputFilter[]{typeFilter});
        edit.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                if (!TextUtils.isEmpty(s)) {
                    int count = 0;
                    int index = 0;
                    int startIndex = 0;
                    while (index < s.length()) {
                        char c = s.charAt(index);
                        if (c < 128) {
                            //英文、数字等
                            count = count + 1;
                        } else {
                            //汉字等
                            count = count + 2;
                        }
                        if (count > MAX_LENGTH) {
                            startIndex = index;
                            break;
                        }
                        index++;
                    }
                    if (startIndex != 0) {
                        ToastUtils.get().showText("超出指定长度");
                        //删除部分字符串 为[x,y) 包含x位置不包含y
                        s.delete(startIndex, s.length());
                    }
                }
            }
        });
    }

    /**
     * 匹配特殊字符，将其过滤
     *
     * @param str 待匹配文本
     * @return 弹框对象
     */
    private String stringFilter(String str) {
        String regEx = "[/:*?<>|\",$!\n\t]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.replaceAll("");
    }

    public DialogView2 setOnClickListener(OnSureListener listener) {
        this.listener = listener;
        return this;
    }

    public DialogView2 setOnClickListener(String content, OnSureListener listener) {
        this.listener = listener;
        if (sureTv != null) {
            sureTv.setText(content);
        }
        return this;
    }

    /**
     * 设置确认按钮事件
     *
     * @param value    是否隐藏取消按钮
     * @param content  确认按钮的显示文本
     * @param listener 回调
     */
    public DialogView2 setOnClickListener(boolean value, String content, OnSureListener listener) {
        if (listener != null) {
            this.listener = listener;
        }
        if (sureTv != null) {
            sureTv.setText(content);
            sureTv.setTextColor(0xFF666666);
            if (value) {
                cancelLl.setVisibility(View.GONE);
            }
        }
        return this;
    }

    public DialogView2 setOnClickListener(OnCancelListener cancelListener) {
        this.cancelListener = cancelListener;
        return this;
    }

    public DialogView2 setOnClickListener(String content, OnCancelListener cancelListener) {
        this.cancelListener = cancelListener;
        if (cancelTv != null) {
            cancelTv.setText(content);
        }
        return this;
    }

    /**
     * 点击Ok按钮后是否dismiss dialog,默认为true
     *
     * @param dismissDialog
     * @return
     */
    public DialogView2 setClickSureDismissDialog(boolean dismissDialog) {
        this.dismissDialog = dismissDialog;
        return this;
    }

    /**
     * 设置edit的文本为空时显示的文本
     *
     * @param hint 文本
     * @return 弹框对象
     */
    public DialogView2 setHint(String hint) {
        if (edit != null) {
            edit.setHint(hint);
            setFontColorRed(false);
        }
        return this;
    }

    /**
     * 设置编辑框内容
     *
     * @param content 文本
     * @return 弹框对象
     */
    public DialogView2 setEditContent(String content) {
        if (edit != null) {
            setFontColorRed(false);
            edit.setText(content);
            edit.setSelection(content.length());
        }
        return this;
    }

    /**
     * 设置文本内容
     *
     * @param content 文本
     * @return 弹框对象
     */
    public DialogView2 setTextContent(String content) {
        if (editLl != null) {
            setFontColorRed(true);
            setDefaultHideInput();
            editLl.setVisibility(View.GONE);
            contentTv.setVisibility(View.VISIBLE);
            contentTv.setText(content);
        }
        return this;
    }

    private void setFontColorRed(boolean value) {
        warnTipIv.setVisibility(value ? View.VISIBLE : View.GONE);
        sureTv.setTextColor(value ? 0xFFFE5660 : 0xFF568BFF);
    }

    /**
     * 隐藏软件盘
     *
     * @return 弹框对象
     */
    public DialogView2 setDefaultHideInput() {
        this.hideInput = true;
        return this;
    }

    /**
     * 编辑框输入文本限制
     *
     * @param hasSigned 是否允许输入正负号
     * @return 弹框对象
     */
    public DialogView2 setContentType(boolean hasSigned) {
        if (edit != null) {
            if (hasSigned) {
                edit.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED | InputType.TYPE_NUMBER_FLAG_DECIMAL);
            } else {
                edit.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
            }
        }
        return this;
    }

    /**
     * 编辑框输入文本限制
     *
     * @param type
     * @return
     */
    public DialogView2 setContentType(int type) {
        if (edit != null) {
            edit.setInputType(type);
        }
        return this;
    }

    /**
     * 小数点的数字限制输入
     *
     * @return
     */
    public DialogView2 setContentNumberType() {
        setContentNumberType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
        return this;
    }

    /**
     * 编辑框输入文本限制只能输入数字
     * InputType.TYPE_NUMBER_FLAG_DECIMAL带小数点的浮点格式
     * InputType.TYPE_CLASS_NUMBER
     *
     * @return
     */
    public DialogView2 setContentNumberType(int type) {
        switch (type) {
            case InputType.TYPE_CLASS_NUMBER:
                //只能为数字
                setContentType(InputType.TYPE_CLASS_NUMBER);
                break;
            case InputType.TYPE_NUMBER_FLAG_SIGNED:
                //有正负号的数字
                setContentType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
                break;
            case InputType.TYPE_NUMBER_FLAG_DECIMAL:
                //小数点的数字限制输入
                setContentType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
                break;
            case 3:
                setContentType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_NUMBER_FLAG_SIGNED);
                break;
        }
        return this;
    }

    /**
     * 字数限制
     *
     * @return
     */
    public DialogView2 setTextLimit(int length) {
        MAX_LENGTH = length;
        return this;
    }

    public DialogView2 setAllowNull(boolean allowNull) {
        this.allowNull = allowNull;
        return this;
    }

    public void dismiss() {
        dialog.dismiss();
    }

    public DialogView2 setCanceledOnTouchOutside(boolean value) {
        isCanceledOnTouchOutside = value;
        return this;
    }

    public interface OnSureListener {
        void onSureClick(String content);
    }

    public interface OnCancelListener {
        void onCancelClick();
    }
}
